// Package lgr An instance of library logger, used for direct output from the command line, etc.
//
// To change logger level should use the system environment "UYMAS_LGR_LEVEL",
// to close logger color style shou use the system environment "UYMAS_LGR_NOCOLOR",
// to change debug maker for test use the system environment "UYMAS_TMP_MARK",
// like:
//
//	# window powershell
//	$env:UYMAS_LGR_LEVEL='all'
//	$env:UYMAS_LGR_NOCOLOR='true'
//	$env:UYMAS_TMP_MARK='TMarkShouldDEL'
//
//	# linux shell
//	export UYMAS_LGR_LEVEL=all
//	export UYMAS_LGR_NOCOLOR=true
//	export UYMAS_TMP_MARK=TMarkShouldDEL
//
// if not info by default.
package lgr

import (
	"errors"
	"fmt"
	"gitee.com/conero/uymas/v2/cli/ansi"
	"gitee.com/conero/uymas/v2/logger"
	"gitee.com/conero/uymas/v2/util/fs"
	"os"
	"path/filepath"
	"runtime"
	"strings"
)

var vLgr *logger.Logger

const (
	// EnvLevelKey try set the lgr level by system environment, like `$ export UYMAS_LGR_LEVEL=info`
	EnvLevelKey = "UYMAS_LGR_LEVEL"
	// EnvNoColorKey try set the lgr no color by system environment, like `$ export UYMAS_LGR_NOCOLOR=true`
	EnvNoColorKey = "UYMAS_LGR_NOCOLOR"
	// EnvMarkKey try set the lgr mark by system environment, like `$ export UYMAS_TMP_MARK=mark`
	EnvMarkKey = "UYMAS_TMP_MARK"
)

func init() {
	lvl := fs.GetenvOr(EnvLevelKey, logger.LevelInfo)
	noColor := strings.ToLower(fs.GetenvOr(EnvNoColorKey, "false"))
	vLgr = logger.NewLogger(logger.Config{
		Level: lvl,
	})
	if noColor != "" && noColor != "false" && noColor != "0" {
		vLgr.NoColor()
	}
}

func Log() logger.Logger {
	return *vLgr
}

func Trace(message string, args ...any) {
	vLgr.Tracef(message, args...)
}

func Debug(message string, args ...any) {
	vLgr.Debugf(message, args...)
}

func Info(message string, args ...any) {
	vLgr.Infof(message, args...)
}

func Warn(message string, args ...any) {
	vLgr.Warnf(message, args...)
}

func Error(message string, args ...any) {
	vLgr.Errorf(message, args...)
}

// ErrorIf print error message only when err is not nil
func ErrorIf(err error, prefixErr ...error) {
	if err == nil {
		return
	}
	vErr := errors.Join(prefixErr...)
	vErr = errors.Join(err, vErr)
	vLgr.Errorf(vErr.Error())
}

func Fatal(message string, args ...any) {
	vLgr.Fatalf(message, args...)
	os.Exit(0)
}

func FatalIf(err error, prefixErr ...error) {
	if err == nil {
		return
	}
	vErr := errors.Join(prefixErr...)
	vErr = errors.Join(err, vErr)
	vLgr.Fatalf(vErr.Error())
	os.Exit(1)
}

func Pref(logPref string) logger.Logger {
	vLgr.Pref(logPref)
	return *vLgr
}

func SetFlag(flag int) {
	vLgr.SetFlags(flag)
}

// TmpMark temporary tags are used for debugging, and debugging should be removed before release
//
// to global search keyword `lgr.TmpMark` then remove it.
func TmpMark(mark any, args ...any) {
	markString := fmt.Sprintf("%v", mark)
	markTitle := fs.GetenvOr(EnvMarkKey, "TMarkShouldDEL")
	_, flPath, flLine, _ := runtime.Caller(1)
	markString = ansi.Style("<"+markTitle+">", ansi.Red, ansi.BkgWhiteBr, ansi.Italic, ansi.Twinkle) +
		ansi.Style(fmt.Sprintf(" %s(%d) ", filepath.Base(flPath), flLine), ansi.Green) +
		markString
	vLgr.Errorf(markString, args...)
}
